package com.sunseagear.wind.common.utils;

import com.sunseagear.common.utils.CacheUtils;
import com.sunseagear.common.utils.SpringContextHolder;
import com.sunseagear.common.utils.StreamUtils;
import com.sunseagear.wind.modules.sys.entity.Menu;
import com.sunseagear.wind.modules.sys.entity.Role;
import com.sunseagear.wind.modules.sys.entity.User;
import com.sunseagear.wind.modules.sys.service.IMenuService;
import com.sunseagear.wind.modules.sys.service.IRoleService;
import com.sunseagear.wind.modules.sys.service.IUserService;
import com.sunseagear.wind.modules.sys.service.impl.MenuServiceImpl;
import com.sunseagear.wind.modules.sys.service.impl.RoleServiceImpl;
import com.sunseagear.wind.modules.sys.service.impl.UserServiceImpl;

import java.util.ArrayList;
import java.util.List;

/**
 *
 * @version V1.0
 * @title UserUtils.java
 * @package com.sunseagear.wind.modules.sys.utils
 * @description: 用户工具类 * @date: 2017年6月26日 下午6:00:39
 * @copyright: 2017 www.sunseagear.com Inc. All rights reserved.
 */
public class UserUtils extends com.sunseagear.common.base.satoken.utils.UserUtils {

    private UserUtils() {
        throw new IllegalStateException("Utility class");
    }


    private static final IUserService userService = SpringContextHolder.getBean(UserServiceImpl.class);
    private static final IRoleService roleService = SpringContextHolder.getBean(RoleServiceImpl.class);
    private static final IMenuService menuService = SpringContextHolder.getBean(MenuServiceImpl.class);

    public static final String USER_CACHE = "sys_user";
    public static final String ONLINE_TOKEN_KEY = "online_tokens:";
    public static final String USER_CACHE_ID = "sys_user:id:";
    public static final String USER_CACHE_USER_NAME = "sys_user:username:";
    public static final String CACHE_ROLE_LIST = "sys_user:role:";
    public static final String CACHE_PERMISSION_LIST = "sys_user:permission:";

    /**
     * 获取当前用户
     *
     * @return 取不到返回 new User()
     */
    public static User getUser() {
        if (UserUtils.isLogin()) {
            return get(UserUtils.getUserId());
        }else {
            return new User();
        }

    }

    /**
     * 根据ID获取用户
     *
     * @return 取不到返回null
     */
    public static User get(Long id) {
        User user = CacheUtils.valueGet(USER_CACHE_ID + id);
        if (user == null) {
            user = userService.getById(id);
            if (user == null) {
                return null;
            }
            CacheUtils.valueSet(USER_CACHE_ID + user.getId(), user);
            CacheUtils.valueSet(USER_CACHE_USER_NAME + user.getUsername(), user);
        }
        return user;
    }

    /**
     * 根据用户名获取用户
     */
    public static User getByUserName(String username) {
        User user = CacheUtils.valueGet(USER_CACHE_USER_NAME + username);
        if (user == null) {
            user = userService.findByUsername(username);
            if (user == null) {
                return null;
            }
            CacheUtils.valueSet(USER_CACHE_ID + user.getId(), user);
            CacheUtils.valueSet(USER_CACHE_USER_NAME + user.getUsername(), user);
        }
        return user;
    }

    /**
     * 获取当前用户角色列表
     */
    public static List<Role> getRoleList() {
        User user = getUser();
        return getRoleList(user.getId());
    }

    private static boolean isNullOrEmpty(List<?> list) {
       return list == null || list.isEmpty();
    }

    public static List<Role> getRoleList(Long userId) {
        List<Role> roleList = CacheUtils.valueGet(CACHE_ROLE_LIST + userId);
        if (isNullOrEmpty(roleList)) {
            roleList = roleService.findListByUserId(userId);
            CacheUtils.valueSet(CACHE_ROLE_LIST + userId, roleList);
        }
        return roleList;
    }

    /**
     * 获取角色列表
     */
    public static List<String> getRoleCodeList() {
        return StreamUtils.toList(getRoleList(),Role::getCode);
    }

    /**
     * 是否有特定的角色
     */
    public static boolean hasRole(String roleCode) {
        return getRoleCodeList().contains(roleCode);
    }

    public static List<String> getPermissionList() {
        final List<String> permissionList = new ArrayList<>();
        getRoleList().forEach(item -> {
            ArrayList<String> cachePermissions = CacheUtils.valueGet(CACHE_PERMISSION_LIST + item.getId());
            permissionList.addAll(isNullOrEmpty(cachePermissions) ? new ArrayList<>() : cachePermissions);
            if (isNullOrEmpty(cachePermissions)) {
                List<Menu> permissionValueList = menuService.findPermissionByRoleId(item.getId());
                List<String> menuIdList = new ArrayList<>();
                for (Menu menu : permissionValueList) {
                    menuIdList.add(menu.getPermission());
                }
                permissionList.addAll(menuIdList);
                // 不加入缓存
                CacheUtils.valueSet(CACHE_PERMISSION_LIST + item.getId(), permissionList);
            }
        });
        return permissionList;
    }


    /**
     * 更新用户
     */
    public static void update(Long id) {
        User user = userService.getById(id);
        if (user == null) {
            return;
        }
        clearCache(user);
        CacheUtils.valueSet(USER_CACHE_ID + user.getId(), user);
        CacheUtils.valueSet(USER_CACHE_USER_NAME + user.getUsername(), user);
        getRoleList();
    }

    /**
     * 清除指定用户缓存
     */
    public static void clearCache(User user) {
        CacheUtils.clear(USER_CACHE_ID + user.getId());
        CacheUtils.clear(USER_CACHE_USER_NAME + user.getUsername());
        CacheUtils.clear(CACHE_ROLE_LIST + user.getId());
    }

    /**
     * 清除权限缓存
     */
    public static void clearPermissionCache(Long roleId) {
        CacheUtils.clear(CACHE_PERMISSION_LIST + roleId);
    }

    /**
     * 清除所有用户的缓存
     */
    public static void clearAllUserCache() {
        CacheUtils.clear(USER_CACHE);
    }
}
